/*
 * Copyright (c) 2011 Jean-Marc Perronne
 * Ensisa, 12 rue des Freres Lumieres, F-68093 Mulhouse cedex
 * All rights reserved.
 *
 * The copyright of this software is owned by Werner Randelshofer. 
 * You may not use, copy or modify this software, except in  
 * accordance with the license agreement you entered into with  
 * Jean-Marc Perronne. For details see accompanying license terms. 
 */

package fr.uha.ensisa.jmp.drone.input.progressive.connexion_3d;

import fr.uha.ensisa.jmp.connexion_3d.Event;
import fr.uha.ensisa.jmp.connexion_3d.Mouse3D;
import fr.uha.ensisa.jmp.connexion_3d.Mouse3DException;
import fr.uha.ensisa.jmp.connexion_3d.Usage;
import fr.uha.ensisa.jmp.drone.at_commands.AtCommand;
import fr.uha.ensisa.jmp.drone.at_commands.AtPcmCommand;
import fr.uha.ensisa.jmp.drone.input.progressive.FlightInputs;

public class MouseHandler implements FlightInputs
{
	private static AtPcmCommand pcmCommand = new AtPcmCommand();
	private Mouse3D mouse;
	private Event read_event, last_event, tmp_event;
	private boolean failed;
	private MouseAdapter inputAdapter;
	private float olr, ofb, oud, orlr;
	
	public MouseHandler(int mouseId, int productId, MouseAdapter inputAdapter)
	{
		this.mouse = new Mouse3D(mouseId, productId);
		this.failed = false;
		this.inputAdapter = inputAdapter;
	}

	public void initialize()
	{
		try
		{
			this.mouse.open();
			this.inputAdapter.mouse(this.mouse);
			Usage usage = this.mouse.usage();
			this.read_event = new Event(usage.buttonsNumber);
			this.last_event = new Event(usage.buttonsNumber);
			this.tmp_event =new Event(usage.buttonsNumber);
			this.failed = false;
			this.olr=this.ofb=this.oud=this.orlr=0;
		}
		catch (Mouse3DException e)
		{
			e.printStackTrace();
			//if (e.what() != Mouse3DException.What.badMouseId) this.mouse.close();
			this.failed = true;;
		}
	}
	
	public void closeMouse()
	{
		this.mouse.close();
	}

	protected AtCommand makeCommand(Event e)
	{
		AtCommand res = null;
		
		float lr = this.inputAdapter.adaptLeftRight(e.ry);
		float fb = this.inputAdapter.adaptFrontBack(e.rx);
		float ud = this.inputAdapter.adaptUpDown(e.tz);
		float rlr = this.inputAdapter.adaptRotateLeftRight(e.rz);
		if ((lr != this.olr) || (fb != this.ofb) || (ud != oud) || (rlr != orlr))
		{
			//System.err.println(String.valueOf(lr) + ' '+ String.valueOf(fb)+ ' '+ String.valueOf(ud)+ ' '+String.valueOf(rlr));

			MouseHandler.pcmCommand.param(true, lr,fb, ud, rlr);
			res = MouseHandler.pcmCommand;
		}
		
		this.olr = lr;
		this.ofb = fb;
		this.oud = ud;
		this.orlr = rlr;

		return res;
	}

	@Override
	public AtCommand command()
	{
		try
		{
				while (this.mouse.readEvent(this.read_event))
					this.tmp_event.affect(this.read_event);
			
				if(!this.tmp_event.equals(last_event))
				{
					this.last_event.affect(this.read_event);
					return this.makeCommand(this.last_event);
				}

		}
		catch (Mouse3DException e)
		{
			e.printStackTrace();
			//if (e.what()!= Mouse3DException.What.badMouseId) mouse.close();
			this.failed = true;
		}
		return null;
	}

	public void inputAdapter(MouseAdapter inputAdapter)
	{
		this.inputAdapter = inputAdapter;
	}
	
	public boolean failed()
	{
		return this.failed;
	}

}
